#include "Wire.h"
#include "def.h"
#include <pins_arduino.h>
#include "uTimerLib.h"
#include "Variables.h"

// 系统时序分析（单位：ms）
// 1. 数据读取：4块 × 25.715 = 102.86（未含传感器转换及I2C开销）
// 2. 数据传输：(2048B+5B)×10bit ÷ 921.6kbps ≈ 22.27
// 3. 单帧周期：102.86 + 22.27 = 125.13 → 理论帧率≈8fps

//实测最高5fps

/********************************************************************
   函数:        ISR()
   功能:        中断服务例程，由定时器触发
   提示：由于 ESP32 的限制，I2C 操作不能直接在 ISR 中执行。
        因此采用标志位机制，将数据读取操作延迟到主循环中执行。
        如果你的微控制器可以在中断中处理I2C，请直接在ISR中读取新的传感器电压值。
 *******************************************************************/
void IRAM_ATTR ISR(void) {

  // 读取新的传感器数据
  if (ReadingRoutineEnable) {
    NewDataAvailable = 1;
  }
}

/********************************************************************
   函数:        setup()
   功能:        初始化设置
 *******************************************************************/
void setup() {

  Serial.begin(921600);  // 初始化串口通信，波特率921600

  //*******************************************************************
  // 使用堆分配内存存储像素常数，替代全局多维数组
  //*******************************************************************
  pixc2_0 = (unsigned long *)heap_caps_malloc(NUMBER_OF_PIXEL * 4, MALLOC_CAP_32BIT);
  if (pixc2_0 == NULL) {
    while(1);
    //Serial.println("堆内存分配失败"); // 调试语句（已注释）
  } else {
    //Serial.println("堆内存分配成功"); // 调试语句（已注释）
    pixc2 = pixc2_0;  // 将指针指向堆内存起始地址
  }

  pinMode(pinLEDred, OUTPUT);
  digitalWrite(pinLEDred, LOW);

  //寻找传感器
  uint8_t error;
  while (error != 0) {
    Wire.begin(); //默认 I2C 引脚(SDA=21, SCL=22)
    Wire.beginTransmission(SENSOR_ADDRESS);
    error = Wire.endTransmission();
    delay(100);
  }

  //读取EEPROM
  Wire.setClock(CLOCK_EEPROM);  // 读取EEPROM 时钟频率为 400kHz
  read_eeprom();

  // 设置传感器通信频率
  Wire.setClock(CLOCK_SENSOR);

  //唤醒传感器
  write_sensor_byte(SENSOR_ADDRESS, CONFIGURATION_REGISTER, 0x01);

  // 将校准设置写入微调寄存器
  write_calibration_settings_to_sensor();

  //打开传感器
  write_sensor_byte(SENSOR_ADDRESS, CONFIGURATION_REGISTER, 0x09);

  //校准
  gradscale_div = pow(2, gradscale);
  vddscgrad_div = pow(2, vddscgrad);
  vddscoff_div = pow(2, vddscoff);
  calcPixC();  // 计算像素常量

  //定时器初始化
  timert = calc_timert(clk_calib, mbit_calib); // 这个值输出为：25715
  TimerLib.setInterval_us(ISR, timert);  //每 timert 微秒调用ISR
}

void loop() {

  if (NewDataAvailable) {
    readblockinterrupt();
    digitalWrite(pinLEDred, !digitalRead(pinLEDred));  // 读取当前状态并取反
    NewDataAvailable = 0;
  }

  if (Serial.available() > 0) {  // 确保有数据再读取
    serial_input = Serial.read();
    switch (serial_input) {
      case 'a':
        print_state = 1;
        break;
      default: break;
    }
  }

  if (state) {
    sort_data();
    state = 0;
    if (print_state == 1) {
      calculate_pixel_temp();
      send_thermal_frame_binary();
      print_state = 0;
    }
  }
}
